home *** CD-ROM | disk | FTP | other *** search
/ Isometric Game Programming with DirectX 7.0 / Isometric Game Programming.iso / source / chapter6 / isohex6_1a / isohex6_1a.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-21  |  10.2 KB  |  415 lines

  1. /*****************************************************************************
  2. IsoHex6_1.cpp
  3. Ernest S. Pazera
  4. 21MAY2000
  5. Start a WIN32 Application Workspace, add in this file
  6. Needs ddraw.lib and dxguid.lib
  7. *****************************************************************************/
  8.  
  9. //////////////////////////////////////////////////////////////////////////////
  10. //INCLUDES
  11. //////////////////////////////////////////////////////////////////////////////
  12. #define WIN32_LEAN_AND_MEAN  
  13.  
  14. #include <windows.h>   
  15. #include "GDICanvas.h"
  16. #include "ddraw.h"
  17.  
  18. //////////////////////////////////////////////////////////////////////////////
  19. //DEFINES
  20. //////////////////////////////////////////////////////////////////////////////
  21. //name for our window class
  22. #define WINDOWCLASS "ISOHEX6"
  23. //title of the application
  24. #define WINDOWTITLE "IsoHex 6-1"
  25.  
  26. //////////////////////////////////////////////////////////////////////////////
  27. //PROTOTYPES
  28. //////////////////////////////////////////////////////////////////////////////
  29. bool Prog_Init();//game data initalizer
  30. void Prog_Loop();//main game loop
  31. void Prog_Done();//game clean up
  32.  
  33. //enumeration functions
  34. HRESULT WINAPI EnumModesCallbackCount(LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext);
  35. HRESULT WINAPI EnumModesCallbackList(LPDDSURFACEDESC2 lpDDSurfaceDesc,LPVOID lpContext);
  36.  
  37. //////////////////////////////////////////////////////////////////////////////
  38. //GLOBALS
  39. //////////////////////////////////////////////////////////////////////////////
  40. HINSTANCE hInstMain=NULL;//main application handle
  41. HWND hWndMain=NULL;//handle to our main window
  42. //IDirectDraw7 Pointer
  43. LPDIRECTDRAW7 lpdd=NULL;
  44. //display mode structure
  45. struct DisplayMode
  46. {
  47.     DWORD dwWidth;
  48.     DWORD dwHeight;
  49.     DWORD dwBPP;
  50. };
  51. //display mode enumeration variables
  52. DWORD dwDisplayModeCount=0;
  53. DisplayMode* DisplayModeList=NULL;
  54.  
  55. //gdicanvas
  56. CGDICanvas gdicBall;
  57.  
  58. //surfaces
  59. LPDIRECTDRAWSURFACE7 lpddsPrime=NULL;
  60. LPDIRECTDRAWSURFACE7 lpddsBack=NULL;
  61.  
  62. //size of the display
  63. DWORD dwDisplayWidth=0;
  64. DWORD dwDisplayHeight=0;
  65.  
  66. //position of the ball
  67. POINT ptBallPosition;
  68. //velocity of the ball
  69. POINT ptBallVelocity;
  70.  
  71. //////////////////////////////////////////////////////////////////////////////
  72. //WINDOWPROC
  73. //////////////////////////////////////////////////////////////////////////////
  74. LRESULT CALLBACK TheWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
  75. {
  76.     //which message did we get?
  77.     switch(uMsg)
  78.     {
  79.     case WM_KEYDOWN:
  80.         {
  81.             //check for escape key
  82.             if(wParam==VK_ESCAPE)
  83.             {
  84.                 DestroyWindow(hWndMain);
  85.             }
  86.  
  87.             return(0);//handled message
  88.         }break;
  89.     case WM_DESTROY://the window is being destroyed
  90.         {
  91.  
  92.             //tell the application we are quitting
  93.             PostQuitMessage(0);
  94.  
  95.             //handled message, so return 0
  96.             return(0);
  97.  
  98.         }break;
  99.     case WM_PAINT://the window needs repainting
  100.         {
  101.             //a variable needed for painting information
  102.             PAINTSTRUCT ps;
  103.             
  104.             //start painting
  105.             HDC hdc=BeginPaint(hwnd,&ps);
  106.  
  107.             /////////////////////////////
  108.             //painting code would go here
  109.             /////////////////////////////
  110.  
  111.             //end painting
  112.             EndPaint(hwnd,&ps);
  113.                         
  114.             //handled message, so return 0
  115.             return(0);
  116.         }break;
  117.     }
  118.  
  119.     //pass along any other message to default message handler
  120.     return(DefWindowProc(hwnd,uMsg,wParam,lParam));
  121. }
  122.  
  123.  
  124. //////////////////////////////////////////////////////////////////////////////
  125. //WINMAIN
  126. //////////////////////////////////////////////////////////////////////////////
  127. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
  128. {
  129.     //assign instance to global variable
  130.     hInstMain=hInstance;
  131.  
  132.     //create window class
  133.     WNDCLASSEX wcx;
  134.  
  135.     //set the size of the structure
  136.     wcx.cbSize=sizeof(WNDCLASSEX);
  137.  
  138.     //class style
  139.     wcx.style=CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  140.  
  141.     //window procedure
  142.     wcx.lpfnWndProc=TheWindowProc;
  143.  
  144.     //class extra
  145.     wcx.cbClsExtra=0;
  146.  
  147.     //window extra
  148.     wcx.cbWndExtra=0;
  149.  
  150.     //application handle
  151.     wcx.hInstance=hInstMain;
  152.  
  153.     //icon
  154.     wcx.hIcon=LoadIcon(NULL,IDI_APPLICATION);
  155.  
  156.     //cursor
  157.     wcx.hCursor=LoadCursor(NULL,IDC_ARROW);
  158.  
  159.     //background color
  160.     wcx.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
  161.  
  162.     //menu
  163.     wcx.lpszMenuName=NULL;
  164.  
  165.     //class name
  166.     wcx.lpszClassName=WINDOWCLASS;
  167.  
  168.     //small icon
  169.     wcx.hIconSm=NULL;
  170.  
  171.     //register the window class, return 0 if not successful
  172.     if(!RegisterClassEx(&wcx)) return(0);
  173.  
  174.     //create main window
  175.     hWndMain=CreateWindowEx(0,WINDOWCLASS,WINDOWTITLE, WS_POPUP | WS_VISIBLE,0,0,320,240,NULL,NULL,hInstMain,NULL);
  176.  
  177.     //error check
  178.     if(!hWndMain) return(0);
  179.  
  180.     //if program initialization failed, then return with 0
  181.     if(!Prog_Init()) return(0);
  182.  
  183.     //message structure
  184.     MSG msg;
  185.  
  186.     //message pump
  187.     for(;;)    
  188.     {
  189.         //look for a message
  190.         if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  191.         {
  192.             //there is a message
  193.  
  194.             //check that we arent quitting
  195.             if(msg.message==WM_QUIT) break;
  196.             
  197.             //translate message
  198.             TranslateMessage(&msg);
  199.  
  200.             //dispatch message
  201.             DispatchMessage(&msg);
  202.         }
  203.  
  204.         //run main game loop
  205.         Prog_Loop();
  206.     }
  207.     
  208.     //clean up program data
  209.     Prog_Done();
  210.  
  211.     //return the wparam from the WM_QUIT message
  212.     return(msg.wParam);
  213. }
  214.  
  215. //////////////////////////////////////////////////////////////////////////////
  216. //INITIALIZATION
  217. //////////////////////////////////////////////////////////////////////////////
  218. bool Prog_Init()
  219. {
  220.     //error code 
  221.     HRESULT hr;
  222.  
  223.     //initialize the dd pointer
  224.     hr=DirectDrawCreateEx(NULL,(void**)&lpdd,IID_IDirectDraw7,NULL);
  225.  
  226.     //example for error handling
  227.     if(FAILED(hr))
  228.     {
  229.         //initialization failed
  230.         return(false);
  231.     }
  232.  
  233.     //set the cooperative level
  234.     lpdd->SetCooperativeLevel(hWndMain,DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT);
  235.  
  236.     //enumerate the displaymodes
  237.     dwDisplayModeCount=0;
  238.  
  239.     lpdd->EnumDisplayModes(0,NULL,NULL,EnumModesCallbackCount);
  240.  
  241.     DisplayModeList=new DisplayMode[dwDisplayModeCount];
  242.     dwDisplayModeCount=0;
  243.  
  244.     lpdd->EnumDisplayModes(0,NULL,NULL,EnumModesCallbackList);
  245.  
  246.     //pick a display mode
  247.     DisplayMode TestMode;
  248.     TestMode.dwWidth=0;
  249.     TestMode.dwHeight=0;
  250.     TestMode.dwBPP=0;
  251.     DWORD index;
  252.     bool found=false;
  253.  
  254.     for(index=0;(index<dwDisplayModeCount);index++)
  255.     {
  256.         if(DisplayModeList[index].dwBPP==16)
  257.         {
  258.             if(DisplayModeList[index].dwWidth>TestMode.dwWidth)
  259.             {
  260.                 TestMode.dwWidth=DisplayModeList[index].dwWidth;
  261.                 TestMode.dwHeight=DisplayModeList[index].dwHeight;
  262.                 TestMode.dwBPP=DisplayModeList[index].dwBPP;
  263.                 found=true;
  264.             }
  265.         }
  266.     }
  267.  
  268.     if(!found)
  269.     {
  270.         return(false);
  271.     }
  272.  
  273.     //set the display mode
  274.     hr=lpdd->SetDisplayMode(TestMode.dwWidth,TestMode.dwHeight,TestMode.dwBPP,0,0);
  275.     //keep display width and height in global variables
  276.     dwDisplayWidth=TestMode.dwWidth;
  277.     dwDisplayHeight=TestMode.dwHeight;
  278.  
  279.     //create the primary surface with a single back buffer
  280.     //clear out a DDSURFACEDESC2
  281.     DDSURFACEDESC2 ddsd;
  282.     memset(&ddsd,0,sizeof(DDSURFACEDESC2));
  283.     ddsd.dwSize=sizeof(DDSURFACEDESC2);
  284.  
  285.     //set the flags for primary surface
  286.     ddsd.dwFlags=DDSD_BACKBUFFERCOUNT | DDSD_CAPS;
  287.     //set back buffer count
  288.     ddsd.dwBackBufferCount=1;
  289.     //set caps
  290.     ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
  291.  
  292.     //create the surface
  293.     lpdd->CreateSurface(&ddsd,&lpddsPrime,NULL);
  294.  
  295.     //clear out a DDSCAPS2
  296.     DDSCAPS2 ddsCaps;
  297.     memset(&ddsCaps,0,sizeof(DDSCAPS2));
  298.  
  299.     //set the caps
  300.     ddsCaps.dwCaps=DDSCAPS_BACKBUFFER;
  301.  
  302.     //retrieve back buffer
  303.     lpddsPrime->GetAttachedSurface(&ddsCaps,&lpddsBack);
  304.  
  305.     //load in the ball image
  306.     gdicBall.Load(NULL,"IsoHex6_1.bmp");
  307.  
  308.     //initialize ball position and velocity
  309.     ptBallPosition.x=0;
  310.     ptBallPosition.y=0;
  311.  
  312.     ptBallVelocity.x=1;
  313.     ptBallVelocity.y=1;
  314.  
  315.     return(true);//return success
  316. }
  317.  
  318. //////////////////////////////////////////////////////////////////////////////
  319. //CLEANUP
  320. //////////////////////////////////////////////////////////////////////////////
  321. void Prog_Done()
  322. {
  323.     //clean up primary surface(this will clean up the back buffer, also)
  324.     if(lpddsPrime)
  325.     {
  326.         lpddsPrime->Release();
  327.         lpddsPrime=NULL;
  328.         lpddsBack=NULL;
  329.     }
  330.  
  331.     //clean up the dd pointer
  332.     if(lpdd)
  333.     {
  334.         lpdd->Release();
  335.         lpdd=NULL;
  336.     }
  337.  
  338.     //clean up gdicanvas
  339.     gdicBall.Destroy();
  340.  
  341.     //get rid of enumeration stuff
  342.     delete [] DisplayModeList;
  343. }
  344.  
  345. //////////////////////////////////////////////////////////////////////////////
  346. //MAIN GAME LOOP
  347. //////////////////////////////////////////////////////////////////////////////
  348. void Prog_Loop()
  349. {
  350.     //set up rectangle for filling
  351.     RECT rcFill;
  352.     SetRect(&rcFill,0,0,dwDisplayWidth,dwDisplayHeight);
  353.  
  354.     //grab dc from back buffer
  355.     HDC hdcSurf;
  356.     lpddsPrime->GetDC(&hdcSurf);
  357.  
  358.     //fill rectangle with black
  359.     FillRect(hdcSurf,&rcFill,(HBRUSH)GetStockObject(BLACK_BRUSH));
  360.  
  361.     //show the ball
  362.     BitBlt(hdcSurf,ptBallPosition.x,ptBallPosition.y,gdicBall.GetWidth(),gdicBall.GetHeight(),gdicBall,0,0,SRCCOPY);
  363.  
  364.     //release dc 
  365.     lpddsPrime->ReleaseDC(hdcSurf);
  366.  
  367.     //move the ball
  368.     ptBallPosition.x+=ptBallVelocity.x;
  369.     ptBallPosition.y+=ptBallVelocity.y;
  370.  
  371.     //bounds checking
  372.     //left side
  373.     if(ptBallPosition.x<=0) ptBallVelocity.x=abs(ptBallVelocity.x);
  374.     //top side
  375.     if(ptBallPosition.y<=0) ptBallVelocity.y=abs(ptBallVelocity.y);
  376.     //right side
  377.     if(ptBallPosition.x>=(int)dwDisplayWidth-gdicBall.GetWidth()) ptBallVelocity.x=-abs(ptBallVelocity.x);
  378.     //bottom side
  379.     if(ptBallPosition.y>=(int)dwDisplayHeight-gdicBall.GetHeight()) ptBallVelocity.y=-abs(ptBallVelocity.y);
  380.  
  381.     //flip surfaces
  382.     //lpddsPrime->Flip(NULL,DDFLIP_WAIT);
  383. }
  384.  
  385. //enumeration-count
  386. HRESULT WINAPI EnumModesCallbackCount(
  387.   LPDDSURFACEDESC2 lpDDSurfaceDesc,  
  388.   LPVOID lpContext                   
  389. )
  390. {
  391.     //increment the count variable
  392.     dwDisplayModeCount++;
  393.  
  394.     //continue the enumeration
  395.     return(DDENUMRET_OK);
  396. }
  397.  
  398. //enumeration-list
  399. HRESULT WINAPI EnumModesCallbackList(
  400.   LPDDSURFACEDESC2 lpDDSurfaceDesc,  
  401.   LPVOID lpContext                   
  402. )
  403. {
  404.     //copy applicable information to the list
  405.     DisplayModeList[dwDisplayModeCount].dwWidth=lpDDSurfaceDesc->dwWidth;
  406.     DisplayModeList[dwDisplayModeCount].dwHeight=lpDDSurfaceDesc->dwHeight;
  407.     DisplayModeList[dwDisplayModeCount].dwBPP=lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount;
  408.  
  409.     //increment the count variable
  410.     dwDisplayModeCount++;
  411.  
  412.     //continue the enumeration
  413.     return(DDENUMRET_OK);
  414. }
  415.